//
//  PSRostovCalculatorTests.m
//  PrefCore
//
//  Created by Sergey on 3/4/14.
//  Copyright (c) 2014 Play-on-smart. All rights reserved.
//

#import <XCTest/XCTest.h>
#import "PSCalculator.h"

#define TARGET_POOL (PSScoreValue)30

@interface PSRostovCalculatorTests : XCTestCase {
    PSCalculator *calc;
    PSGame *game;
    PSGameSettings *settings;
}

@end

@implementation PSRostovCalculatorTests

-(void)setUp {
    [super setUp];
    calc = [PSCalculator calculatorForGameFlavor:kGameFlavorRostov];
    NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
    [PSGameSettings clearUserDefaults:ud];
    [ud synchronize];
    settings = [PSGameSettings settingsFromUserDefaults:ud];
    settings.poolSize = TARGET_POOL;
    game = [[PSGame alloc] init];
}

-(void)testInit {
    XCTAssertNotNil(calc);
}

-(void)testWriteToPoolAllOthersClosed {
    [[game scoreForPlayerId:0].pool addValue:TARGET_POOL-1];
    [[game scoreForPlayerId:1].pool addValue:TARGET_POOL];
    [[game scoreForPlayerId:2].pool addValue:TARGET_POOL];
    PSScorer *scorer = [PSScorer trickingTwoPassesScorer];
    [game setCurrentBid:[PSBid bidPlayWithTrump:kSuitClubs tricks:9] forPlayer:0];
    [scorer updateGame:game withSettings:settings andCalculator:calc];
    XCTAssertEqual(TARGET_POOL, [game scoreForPlayerId:0].pool.current);
    XCTAssertEqual(35, [game scoreForPlayerId:0].whists[1].current);
    XCTAssertEqual(35, [game scoreForPlayerId:0].whists[2].current);
}

-(void)testWriteToPoolReducePlayerMountain {
    [[game scoreForPlayerId:0].pool addValue:TARGET_POOL-1];
    [[game scoreForPlayerId:0].mountain addValue:3];
    [[game scoreForPlayerId:1].pool addValue:TARGET_POOL];
    [[game scoreForPlayerId:2].pool addValue:TARGET_POOL];
    PSScorer *scorer = [PSScorer trickingTwoPassesScorer];
    [game setCurrentBid:[PSBid bidPlayWithTrump:kSuitClubs tricks:9] forPlayer:0];
    [scorer updateGame:game withSettings:settings andCalculator:calc];
    XCTAssertEqual(TARGET_POOL, [game scoreForPlayerId:0].pool.current);
    XCTAssertEqual(0, [game scoreForPlayerId:0].mountain.current);
    XCTAssertEqual(20, [game scoreForPlayerId:0].whists[1].current);
    XCTAssertEqual(20, [game scoreForPlayerId:0].whists[2].current);
}

-(void)testWriteToPoolReduceOpponentMountain {
    for (PSPlayerId hasMountain = 1 ; hasMountain <= 2 ; hasMountain++) {
        PSPlayerId other = 3 - hasMountain;
        game = [[PSGame alloc] init];
        [[game scoreForPlayerId:0].pool addValue:TARGET_POOL-1];
        [[game scoreForPlayerId:1].pool addValue:TARGET_POOL];
        [[game scoreForPlayerId:2].pool addValue:TARGET_POOL];
        [[game scoreForPlayerId:hasMountain].mountain addValue:3];
        PSScorer *scorer = [PSScorer trickingTwoPassesScorer];
        [game setCurrentBid:[PSBid bidPlayWithTrump:kSuitClubs tricks:9] forPlayer:0];
        [scorer updateGame:game withSettings:settings andCalculator:calc];
        XCTAssertEqual(TARGET_POOL, [game scoreForPlayerId:0].pool.current);
        XCTAssertEqual(2, [game scoreForPlayerId:hasMountain].mountain.current);
        XCTAssertEqual(40, [game scoreForPlayerId:0].whists[hasMountain].current);
        XCTAssertEqual(15, [game scoreForPlayerId:0].whists[other].current);
    }
}

-(void)testWritingToPoolReducesTheMountain {
    [[game scoreForPlayerId:0].pool addValue:TARGET_POOL];
    [[game scoreForPlayerId:1].pool addValue:TARGET_POOL];
    [[game scoreForPlayerId:2].pool addValue:TARGET_POOL];
    [[game scoreForPlayerId:0].mountain addValue:1];
    [[game scoreForPlayerId:1].mountain addValue:2];
    [[game scoreForPlayerId:2].mountain addValue:3];
    PSScorer *scorer = [PSScorer trickingTwoPassesScorer];
    [game setCurrentBid:[PSBid bidPlayWithTrump:kSuitClubs tricks:9] forPlayer:0];
    [scorer updateGame:game withSettings:settings andCalculator:calc];
    XCTAssertEqual(0, [game scoreForPlayerId:0].mountain.current);
    XCTAssertEqual(0, [game scoreForPlayerId:1].mountain.current);
    XCTAssertEqual(0, [game scoreForPlayerId:2].mountain.current);
    XCTAssertEqual(30, [game scoreForPlayerId:0].whists[1].current);
    XCTAssertEqual(40, [game scoreForPlayerId:0].whists[2].current);
}

-(void)testHelpOpponentsClosePools {
    [[game scoreForPlayerId:0].pool addValue:TARGET_POOL];
    [[game scoreForPlayerId:1].pool addValue:TARGET_POOL];
    [[game scoreForPlayerId:2].pool addValue:TARGET_POOL-2];
    [[game scoreForPlayerId:0].mountain addValue:1];
    [[game scoreForPlayerId:2].mountain addValue:1];
    PSScorer *scorer = [PSScorer trickingTwoPassesScorer];
    [game setCurrentBid:[PSBid bidPlayWithTrump:kSuitClubs tricks:9] forPlayer:0];
    [scorer updateGame:game withSettings:settings andCalculator:calc];
    XCTAssertEqual(0, [game scoreForPlayerId:0].mountain.current);
    XCTAssertEqual(0, [game scoreForPlayerId:1].mountain.current);
    XCTAssertEqual(0, [game scoreForPlayerId:2].mountain.current);
    XCTAssertEqual(TARGET_POOL, [game scoreForPlayerId:0].pool.current);
    XCTAssertEqual(TARGET_POOL, [game scoreForPlayerId:1].pool.current);
    XCTAssertEqual(TARGET_POOL, [game scoreForPlayerId:2].pool.current);
    XCTAssertEqual(10, [game scoreForPlayerId:0].whists[1].current);
    XCTAssertEqual(50, [game scoreForPlayerId:0].whists[2].current);
}

-(void)testMissedTrick {
    PSScorer *scorer = [PSScorer trickingScorer];
    [game setCurrentBid:[PSBid bidPlayWithTrump:kSuitClubs tricks:6] forPlayer:0];
    [game setCurrentBid:[PSBid bidWhist] forPlayer:1];
    [game setCurrentBid:[PSBid bidPass] forPlayer:2];
    game.player.opponent = 1;
    game.player.passer = 2;
    [game setTricks:5 ofPlayer:0];
    [game setTricks:5 ofPlayer:1];
    [scorer updateGame:game withSettings:settings andCalculator:calc];
    XCTAssertEqual(2, [game scoreForPlayerId:0].mountain.current);
}

@end
